#!/usr/bin/env python3
"""
大众点评爬虫 P4 版本 - 城市管理器
负责城市配置、验证和单城市爬行支持
"""

import logging
from typing import Dict, List, Optional, Tuple, Any
from playwright.sync_api import sync_playwright
from pathlib import Path
import sys

# 添加配置路径
sys.path.append(str(Path(__file__).parent.parent))
from config.settings import ConfigManager, get_cookie_string

logger = logging.getLogger(__name__)

class CityManager:
    """城市管理器 - 负责城市配置和验证"""
    
    def __init__(self):
        self.config_manager = ConfigManager()
        self.cookie_string = get_cookie_string()
        self.validated_cities = {}
        
    def get_all_cities(self) -> Dict[str, Dict[str, Any]]:
        """获取所有城市配置"""
        return self.config_manager.get_cities()
    
    def get_city_list(self) -> List[Tuple[str, str]]:
        """获取城市列表 (name, code) 格式"""
        cities = self.get_all_cities()
        return [(name, info['code']) for name, info in cities.items()]
    
    def get_validated_cities(self) -> List[Tuple[str, str]]:
        """获取已验证的城市列表"""
        cities = self.config_manager.get_validated_cities()
        return [(name, info['code']) for name, info in cities.items()]
    
    def get_city_by_name(self, city_name: str) -> Optional[Dict[str, Any]]:
        """根据城市名获取城市信息"""
        return self.config_manager.get_city_info(city_name)
    
    def parse_cookies(self) -> List[Dict[str, str]]:
        """解析Cookie字符串为Playwright格式"""
        cookies = []
        for cookie_pair in self.cookie_string.split('; '):
            if '=' in cookie_pair:
                name, value = cookie_pair.split('=', 1)
                cookies.append({
                    'name': name.strip(),
                    'value': value.strip(),
                    'domain': '.dianping.com',
                    'path': '/'
                })
        logger.info(f"[CITY_MANAGER] 解析了 {len(cookies)} 个Cookie")
        return cookies
    
    def validate_city_accessibility(self, city_name: str, city_code: str) -> Tuple[bool, str]:
        """验证城市可访问性"""
        logger.info(f"[CITY_MANAGER] 验证城市可访问性: {city_name} ({city_code})")
        
        try:
            test_url = f"https://www.dianping.com/{city_code}/ch10"
            
            with sync_playwright() as p:
                browser = p.chromium.launch(headless=True)
                context = browser.new_context()
                
                cookies = self.parse_cookies()
                context.add_cookies(cookies)
                page = context.new_page()
                
                try:
                    page.goto(test_url, timeout=30000)
                    page.wait_for_load_state('networkidle', timeout=20000)
                    
                    # 检查页面是否正常加载
                    if 'login' in page.url.lower():
                        logger.warning(f"[CITY_MANAGER] {city_name} Cookie可能失效")
                        return False, "Cookie失效"
                    
                    # 检查页面标题
                    title = page.title()
                    if '美食' in title or city_name in title:
                        logger.info(f"[CITY_MANAGER] ✅ {city_name} 验证通过")
                        # 更新验证状态
                        self.config_manager.update_city_validation(city_name, True)
                        return True, "验证通过"
                    else:
                        logger.warning(f"[CITY_MANAGER] ❌ {city_name} 页面内容异常: {title}")
                        return False, f"页面异常: {title}"
                        
                except Exception as e:
                    logger.error(f"[CITY_MANAGER] {city_name} 访问异常: {e}")
                    return False, f"访问异常: {str(e)[:50]}"
                
                finally:
                    browser.close()
                    
        except Exception as e:
            logger.error(f"[CITY_MANAGER] {city_name} 验证失败: {e}")
            return False, f"验证失败: {str(e)[:50]}"
    
    def validate_all_cities(self) -> Dict[str, Tuple[bool, str]]:
        """验证所有城市的可访问性"""
        logger.info("[CITY_MANAGER] 开始验证所有城市可访问性")
        
        cities = self.get_all_cities()
        results = {}
        
        for city_name, city_info in cities.items():
            city_code = city_info['code']
            is_valid, message = self.validate_city_accessibility(city_name, city_code)
            results[city_name] = (is_valid, message)
            
            # 添加延迟避免请求过快
            import time
            time.sleep(2)
        
        # 统计结果
        valid_count = sum(1 for is_valid, _ in results.values() if is_valid)
        total_count = len(results)
        
        logger.info(f"[CITY_MANAGER] 城市验证完成: {valid_count}/{total_count} 个城市可访问")
        
        return results
    
    def get_single_city_config(self, city_name: str) -> Optional[Dict[str, Any]]:
        """获取单城市爬行配置"""
        city_info = self.get_city_by_name(city_name)
        if not city_info:
            logger.error(f"[CITY_MANAGER] 未找到城市: {city_name}")
            return None
        
        # 验证城市可访问性
        is_valid, message = self.validate_city_accessibility(city_name, city_info['code'])
        if not is_valid:
            logger.error(f"[CITY_MANAGER] 城市验证失败: {city_name} - {message}")
            return None
        
        return {
            'name': city_name,
            'code': city_info['code'],
            'region': city_info.get('region', '未知'),
            'validated': True,
            'crawl_settings': self.config_manager.get_crawl_settings()
        }
    
    def is_city_supported(self, city_name: str) -> bool:
        """检查城市是否在支持列表中"""
        cities = self.get_all_cities()
        return city_name in cities
    
    def get_city_priority_order(self) -> List[Tuple[str, str]]:
        """按优先级获取城市列表"""
        cities = self.get_all_cities()
        sorted_cities = sorted(
            cities.items(), 
            key=lambda x: x[1].get('priority', 999)
        )
        return [(name, info['code']) for name, info in sorted_cities]
    
    def get_region_cities(self, region: str) -> List[Tuple[str, str]]:
        """获取指定地区的城市"""
        cities = self.get_all_cities()
        region_cities = [
            (name, info['code']) 
            for name, info in cities.items() 
            if info.get('region') == region
        ]
        return region_cities
    
    def update_city_status(self, city_name: str, validated: bool, **kwargs):
        """更新城市状态"""
        self.config_manager.update_city_validation(city_name, validated)
        
        # 可以扩展更新其他状态信息
        if kwargs:
            logger.info(f"[CITY_MANAGER] 更新 {city_name} 额外状态: {kwargs}")
    
    def get_crawl_summary(self) -> Dict[str, Any]:
        """获取爬取摘要信息"""
        cities = self.get_all_cities()
        validated_cities = self.get_validated_cities()
        
        return {
            'total_cities': len(cities),
            'validated_cities': len(validated_cities),
            'regions': list(set(info.get('region', '未知') for info in cities.values())),
            'crawl_settings': self.config_manager.get_crawl_settings(),
            'quality_standards': self.config_manager.get_quality_standards()
        }
